package com.bryantkobe.myspringcode.service;

import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ZSetOperations;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @description: Redis相关服务接口
 * @author: alienwarezzl
 * @date: 2025/9/21
 */
public interface MRedisService {

    /**
     * 设置字符串值
     * @param key 键
     * @param value 值
     */
    public void set(String key, String value);

    /**
     * 设置字符串值并设置过期时间
     * @param key     键
     * @param value   值
     * @param timeout 过期时间
     * @param unit    时间单位
     */
    public void setWithExpire(String key, Object value, long timeout, TimeUnit unit);

    /**
     * 判断键是否存在
     * @param key 键
     * @return 是否存在
     */
    public Boolean hasKey(String key);

    /**
     * 根据键获取值
     * @param key 键
     * @return 值
     */
    public Object get(String key);

    /**
     * 删除键
     * @param key 键
     * @return 值
     */
    public Boolean delete(String key);

    /**
     * 设置过期时间
     * @param key     键
     * @param timeout 过期时间
     * @param unit    时间单位
     * @return 是否设置成功
     */
    public Boolean expire(String key, long timeout, TimeUnit unit);

    /**
     * 获取剩余过期时间
     * @param key  键
     * @param unit 时间单位
     * @return 剩余时间
     */
    public Long getExpire(String key, TimeUnit unit);

    /**
     * 递增
     * @param key   键
     * @param delta 增量
     * @return 递增后的值
     */
    public Long increment(String key, long delta);

    /**
     * 递减
     * @param key   键
     * @param delta 减量
     * @return 递减后的值
     */
    public Long decrement(String key, long delta);

    /**
     * 获取列表操作接口
     * @return ListOperations
     */
    public ListOperations<String, Object> opsForList();

    /**
     * 在列表左侧添加元素
     * @param key   键
     * @param value 值
     * @return 添加后列表的长度
     */
    public Long leftPush(String key, Object value);

    /**
     * 在列表左侧批量添加元素
     * @param key    键
     * @param values 值集合
     * @return 添加后列表的长度
     */
    public Long leftPushAll(String key, Object... values);

    /**
     * 在列表右侧添加元素
     * @param key   键
     * @param value 值
     * @return 添加后列表的长度
     */
    public Long rightPush(String key, Object value);

    /**
     * 在列表右侧批量添加元素
     * @param key    键
     * @param values 值集合
     * @return 添加后列表的长度
     */
    public Long rightPushAll(String key, Object... values);

    /**
     * 从列表左侧弹出元素
     * @param key 键
     * @return 弹出的元素
     */
    public Object leftPop(String key);

    /**
     * 从列表右侧弹出元素
     * @param key 键
     * @return 弹出的元素
     */
    public Object rightPop(String key);

    /**
     * 获取列表指定范围内的元素
     * @param key   键
     * @param start 开始索引
     * @param end   结束索引
     * @return 元素列表
     */
    public List<Object> range(String key, long start, long end);

    /**
     * 获取列表长度
     * @param key 键
     * @return 列表长度
     */
    public Long listSize(String key);

    /**
     * 根据索引获取列表中的元素
     * @param key   键
     * @param index 索引
     * @return 元素
     */
    public Object listIndex(String key, long index);

    /**
     * 根据索引设置列表元素的值
     * @param key   键
     * @param index 索引
     * @param value 值
     */
    public void listSet(String key, long index, Object value);

    /**
     * 从列表中删除指定数量的值
     * @param key   键
     * @param count 删除数量
     * @param value 值
     * @return 删除的数量
     */
    public Long listRemove(String key, long count, Object value);

    /**
     * 获取哈希操作接口
     * @return HashOperations
     */
    public HashOperations<String, Object, Object> opsForHash();

    /**
     * 向哈希表中添加一个元素
     * @param key     键
     * @param hashKey 哈希键
     * @param value   值
     */
    public void hashPut(String key, Object hashKey, Object value);

    /**
     * 向哈希表中批量添加元素
     * @param key 键
     * @param map 哈希键值对
     */
    public void hashPutAll(String key, Map<Object, Object> map);

    /**
     * 获取哈希表中的元素
     * @param key     键
     * @param hashKey 哈希键
     * @return 值
     */
    public Object hashGet(String key, Object hashKey);

    /**
     * 获取哈希表中所有键值对
     * @param key 键
     * @return 键值对映射
     */
    public Map<Object, Object> hashEntries(String key);

    /**
     * 删除哈希表中的元素
     * @param key      键
     * @param hashKeys 哈希键数组
     * @return 删除的数量
     */
    public Long hashDelete(String key, Object... hashKeys);

    /**
     * 判断哈希表中是否存在某个键
     * @param key     键
     * @param hashKey 哈希键
     * @return 是否存在
     */
    public Boolean hashHasKey(String key, Object hashKey);
    /**
     * 获取哈希表中所有键
     * @param key 键
     * @return 键集合
     */
    public Set<Object> hashKeys(String key);

    /**
     * 获取哈希表中所有值
     * @param key 键
     * @return 值集合
     */
    public List<Object> hashValues(String key);

    /**
     * 获取哈希表大小
     * @param key 键
     * @return 大小
     */
    public Long hashSize(String key);

    /**
     * 哈希表中字段值增加
     * @param key     键
     * @param hashKey 哈希键
     * @param delta   增量
     * @return 增加后的值
     */
    public Long hashIncrement(String key, Object hashKey, long delta);

    /**
     * 哈希表中字段值减少
     * @param key     键
     * @param hashKey 哈希键
     * @param delta   减量
     * @return 减少后的值
     */
    public Long hashDecrement(String key, Object hashKey, long delta);

    /**
     * 获取集合操作接口
     * @return SetOperations
     */
    public SetOperations<String, Object> opsForSet();

    /**
     * 向集合中添加元素
     * @param key    键
     * @param values 值数组
     * @return 添加成功的数量
     */
    public Long setAdd(String key, Object... values);

    /**
     * 从集合中移除元素
     * @param key    键
     * @param values 值数组
     * @return 移除的数量
     */
    public Long setRemove(String key, Object... values);

    /**
     * 从集合中随机弹出一个元素
     * @param key 键
     * @return 元素
     */
    public Object setPop(String key);

    /**
     * 获取集合中的所有元素
     * @param key 键
     * @return 元素集合
     */
    public Set<Object> setMembers(String key);

    /**
     * 判断元素是否在集合中
     * @param key   键
     * @param value 值
     * @return 是否存在
     */
    public Boolean setIsMember(String key, Object value);

    /**
     * 获取集合的大小
     * @param key 键
     * @return 大小
     */
    public Long setSize(String key);

    /**
     * 获取多个集合的并集
     * @param keys 键数组
     * @return 并集
     */
    public Set<Object> setUnion(String... keys);

    /**
     * 获取多个集合的交集
     * @param keys 键数组
     * @return 交集
     */
    public Set<Object> setIntersect(String... keys);

    /**
     * 获取多个集合的差集
     * @param keys 键数组
     * @return 差集
     */
    public Set<Object> setDifference(String... keys);

    /**
     * 获取有序集合操作接口
     * @return ZSetOperations
     */
    public ZSetOperations<String, Object> opsForZSet();

    /**
     * 向有序集合中添加元素
     * @param key   键
     * @param value 值
     * @param score 分数
     * @return 是否添加成功
     */
    public Boolean zSetAdd(String key, Object value, double score);

    /**
     * 批量向有序集合中添加元素
     * @param key         键
     * @param valueScores 值-分数元组集合
     * @return 添加的数量
     */
    public Long zSetAdd(String key, Set<ZSetOperations.TypedTuple<Object>> valueScores);

    /**
     * 从有序集合中移除元素
     * @param key    键
     * @param values 值数组
     * @return 移除的数量
     */
    public Long zSetRemove(String key, Object... values);

    /**
     * 增加有序集合中元素的分数
     * @param key   键
     * @param value 值
     * @param delta 增量
     * @return 增加后的分数
     */
    public Double zSetIncrementScore(String key, Object value, double delta);

    /**
     * 获取有序集合中元素的排名(从小到大)
     * @param key   键
     * @param value 值
     * @return 排名(从0开始)
     */
    public Long zSetRank(String key, Object value);

    /**
     * 获取有序集合中元素的排名(从大到小)
     * @param key   键
     * @param value 值
     * @return 排名(从0开始)
     */
    public Long zSetReverseRank(String key, Object value);

    /**
     * 获取有序集合中指定排名范围的元素(从小到大)
     * @param key   键
     * @param start 开始排名
     * @param end   结束排名
     * @return 元素集合
     */
    public Set<Object> zSetRange(String key, long start, long end);

    /**
     * 获取有序集合中指定排名范围的元素(从大到小)
     * @param key   键
     * @param start 开始排名
     * @param end   结束排名
     * @return 元素集合
     */
    public Set<Object> zSetReverseRange(String key, long start, long end);

    /**
     * 获取有序集合中指定分数范围的元素(从小到大)
     * @param key 键
     * @param min 最小分数
     * @param max 最大分数
     * @return 元素集合
     */
    public Set<Object> zSetRangeByScore(String key, double min, double max);

    /**
     * 获取有序集合中指定分数范围的元素(从大到小)
     * @param key 键
     * @param min 最小分数
     * @param max 最大分数
     * @return 元素集合
     */
    public Set<Object> zSetReverseRangeByScore(String key, double min, double max);

    /**
     * 获取有序集合中指定分数范围的元素(带分数)
     * @param key 键
     * @param min 最小分数
     * @param max 最大分数
     * @return 元素-分数元组集合
     */
    public Set<ZSetOperations.TypedTuple<Object>> zSetRangeByScoreWithScores(String key, double min, double max);

    /**
     * 获取有序集合的大小
     * @param key 键
     * @return 大小
     */
    public Long zSetSize(String key);

    /**
     * 获取有序集合中指定分数范围内的元素数量
     * @param key 键
     * @param min 最小分数
     * @param max 最大分数
     * @return 数量
     */
    public Long zSetCount(String key, double min, double max);

    /**
     * 获取有序集合中元素的分数
     * @param key   键
     * @param value 值
     * @return 分数
     */
    public Double zSetScore(String key, Object value);

    /**
     * 移除有序集合中指定排名范围的元素
     * @param key   键
     * @param start 开始排名
     * @param end   结束排名
     * @return 移除的数量
     */
    public Long zSetRemoveRange(String key, long start, long end);

    /**
     * 移除有序集合中指定分数范围的元素
     * @param key 键
     * @param min 最小分数
     * @param max 最大分数
     * @return 移除的数量
     */
    public Long zSetRemoveRangeByScore(String key, double min, double max);

    /**
     * 开启事务
     */
    public void multi();

    /**
     * 执行事务
     * @return 事务结果
     */
    public List<Object> exec();

    /**
     * 放弃事务
     */
    public void discard();

    /**
     * 发布消息
     * @param channel 频道
     * @param message 消息
     */
    public void convertAndSend(String channel, Object message);
}
